﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Web.Ajax.Controls;
using System.Reflection;

namespace Web.Ajax.Testing
{
	public class TestTree
	{
		public static TreeData[] GetPropertiesAndTests(Type t, TestGroup tg)
		{
			var tests = new List<TreeData>();
			var props = t.GetProperties();
			var staticmethods = t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);

			var TestGroup = Activator.CreateInstance(t);
			foreach (var p in props)
			{
				var attributes = p.GetCustomAttributes(typeof(TestProperty), false);
				if (attributes == null || attributes.Length == 0)
					continue;
				var td = new TreeData();
				td.Title = "<b>" + p.Name + ": </b>" + p.GetValue(TestGroup, null).ToString();
				td.Resource = Web.Ajax.Resources.Images.Tag;
				td.Order = int.MinValue;
				td.Selectable = false;
				tests.Add(td);
			}

			foreach (var sm in staticmethods)
			{
				var attributes = sm.GetCustomAttributes(typeof(Test), false);
				if (attributes == null || attributes.Length == 0)
					continue;

				var a = (Test)attributes[0];
				var td = new TreeData();
				td.Title = a.Name;
				td.Resource = "Question.gif";
				td.Attributes = new System.Collections.Hashtable();
				td.Id = sm.DeclaringType.AssemblyQualifiedName + "|" + sm.Name;
				td.Attributes["Test"] = true;
				td.Attributes["Name"] = a.Name;
				td.OnTitleClick = Json.FunctionCallScript("ShowTestDescription", td.Id, "pre:this");
				td.Order = a.Order;
				tests.Add(td);
			}
			tests.Sort();
			return tests.ToArray();
		}

		public static TreeData[] GetGroups(Assembly a)
		{
			var groups = new List<TreeData>();

			var tps=a.GetTypes();

			foreach (var t in tps)
			{
				var attributes = t.GetCustomAttributes(typeof(Web.Ajax.Testing.TestGroup), true);
				if (attributes == null || attributes.Length == 0)
					continue;
				var tg = (Web.Ajax.Testing.TestGroup)attributes[0];
				var g = new TreeData();
				g.Title = tg.Name == null ? "Test Group" : tg.Name;
				g.Resource = Web.Ajax.Resources.Images.Folder;
				g.Children = GetPropertiesAndTests(t, tg);
				g.Order = tg.Order;
				//g.Min = 0;
				//g.Max = int.MaxValue;

				groups.Add(g);
			}
			groups.Sort();
			return groups.ToArray();
		}

		public static TreeData[] GetTreeData(TreeInfo ti)
		{
			var root = new TreeData();
			root.Title = "Tests";
			root.Children = GetGroups(System.Reflection.Assembly.GetCallingAssembly());
			ti.OnComplete = "TreeLoaded();";
			return new TreeData[] { root };
		}

		public class TestResponse : SimpleResponse
		{
			public string[] Script;
		}

		[Ajax(Name = "Ajax.RunTest")]
		public static TestResponse RunTest(string typeandmethod)
		{
			var response = new TestResponse();
			try
			{
				var parts = typeandmethod.Split('|');
				var type = parts[0];
				var method = parts[1];

				response.Data = typeandmethod;
				var t = Type.GetType(type);


				MethodInfo Method = null;
				if (t != null)
					Method = t.GetMethod(method);
				var res = (TestResult)Method.Invoke(null, null);
				if (res == null)
					throw new Exception("Test did not return a valid result.");
				response.Success = res.Result;
				response.Message = res.Message;
				response.Script = res.Script;
			}
			catch (Exception ex)
			{
				response.Success = false;
				if (ex.InnerException != null)
					ex = ex.InnerException;
				response.Message = ex.Message;
			}
			return response;
		}
	}
}
